using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace FoundationLib.AddIns.Constraints.Visitors
{
	/// <summary>
	/// Represents a visitor evaluating complex OCL collection statements
	/// </summary>
	public class ComplexCollectionVisitor : RegexVisitor
	{
		private const string PATTERN = @"([^- ]+)->([^\(]+)\(([^\|]+)\|([^\)]+)\)";
		private readonly string[] ignoreLoops = new string[] { "forAll", "exists" };

		/// <summary>
		/// Creates a new complex collection visitor
		/// </summary>
		public ComplexCollectionVisitor()
			: base(PATTERN)
		{
		}

		private string ConvertComplexOperation(string root, string operation, string quantifier, string expression)
		{
			switch (operation)
			{
				case "sum":
					return root + ".Sum(" + quantifier.Trim() + " => " + expression.Trim() + ")";
				case "select":
					return root + ".Where(" + quantifier.Trim() + " => " + expression.Trim() + ")";
				case "sortedBy":
					return root + ".OrderBy(" + quantifier.Trim() + " => " + expression.Trim() + ")";
				default:
					return root;
			}
		}

		/// <summary>
		/// Evaluates regular expession matches
		/// </summary>
		/// <returns>The result of the evaluation</returns>
		/// <param name="match">The regular expression match</param>
		protected override string Evaluate(Match match)
		{
			if (ignoreLoops.Any(x => x == match.Groups[2].Value))
				return match.Groups[0].Value;
			else
				return this.ConvertComplexOperation(match.Groups[1].Value, match.Groups[2].Value, match.Groups[3].Value, match.Groups[4].Value);
		}
	}
}
